package main

import (
	"fmt"
	"math/rand"
	"time"
)

func generator() chan int {
	out := make(chan int)
	go func() {
		i := 0
		for {
			time.Sleep(time.Duration(rand.Intn(1500)) * time.Millisecond)
			out <- i
			i++
		}
	}()
	return out
}

func worker(id int, c chan int) {
	for n := range c {
		time.Sleep(time.Second) // 模拟消费数据慢的场景
		fmt.Printf("Worker %d received %d\n", id, n)
	}
}

func createWorker(id int) chan<- int {
	c := make(chan int)
	go worker(id, c)
	return c
}

//func main() {
//	//var c1, c2 chan int // c1 and c2 = nil
//	var c1, c2 = generator(), generator()
//	//w := createWorker(0)
//	var worker = createWorker(0)
//
//	n := 0
//	hasValue := false
//	for {
//		var activeWorker chan<- int // nil channel
//		if hasValue {
//			activeWorker = worker
//		}
//
//		// 如果消费数据慢，之前的数据未保存，会被覆盖掉
//		select {
//		case n = <-c1:
//			//fmt.Println("Received from c1:", n)
//			//w <- n
//			hasValue = true
//		case n = <-c2:
//			//fmt.Println("Received from c2:", n)
//			//w <- n
//			hasValue = true
//		case activeWorker <- n: // nil channel会被阻塞
//			hasValue = false
//			//default:
//			//	fmt.Println("No value received")
//		}
//	}
//}

// 如果消费数据慢，之前的数据未保存，会被覆盖掉
func main() {
	var c1, c2 = generator(), generator()
	var worker = createWorker(0)

	var values []int // 缓存数据，解决生产和消费速率不一致的问题
	tm := time.After(10 * time.Second)
	tick := time.Tick(time.Second) // 定时查看values长度
	for {
		var activeWorker chan<- int
		var activeValue int
		if len(values) > 0 {
			activeWorker = worker
			activeValue = values[0]
		}

		select {
		case n := <-c1:
			values = append(values, n)
		case n := <-c2:
			values = append(values, n)
		case activeWorker <- activeValue: // nil channel会被阻塞
			values = values[1:]
		case <-time.After(800 * time.Millisecond): // 数据生成太慢的情况，相邻两次数据的时间
			fmt.Println("timeout")
		case <-tick:
			fmt.Println("queue len =", len(values))
		case <-tm:
			fmt.Println("bye")
			return
		}
	}
}
